package com.tanhua.server.service;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.RandomUtil;
import com.alibaba.fastjson.JSON;
import com.tanhua.autoconfig.template.HuanXinTemplate;
import com.tanhua.commons.utils.Constants;
import com.tanhua.dubbo.api.*;
import com.tanhua.model.domain.Question;
import com.tanhua.model.domain.UserInfo;
import com.tanhua.model.dto.RecommendUserDto;
import com.tanhua.model.mongo.RecommendUser;
import com.tanhua.model.mongo.Visitors;
import com.tanhua.model.vo.ErrorResult;
import com.tanhua.model.vo.NearUserVo;
import com.tanhua.model.vo.PageResult;
import com.tanhua.model.vo.TodayBest;
import com.tanhua.server.exception.BusinessException;
import com.tanhua.server.interceptor.UserHolder;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @author 刘付磊
 * @date 2021/11/15 0015
 */
@Service
public class TanhuaService {

    @DubboReference
    private RecommendUserApi recommendUserApi;

    @DubboReference
    private UserInfoApi userInfoApi;

    @DubboReference
    private QuestionApi questionApi;

    @Autowired
    private HuanXinTemplate template;

    @DubboReference
    private UserLikeApi userLikeApi;

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    @DubboReference
    private UserLocationApi userLocationApi;

    @Value("${tanhua.default.recommend.users}")
    private String recommendUser;

    @Autowired
    private MessagesService messagesService;

    @DubboReference
    private VisitorsApi visitorsApi;

    //查询今日佳人数据
    public TodayBest todayBest() {
        //1.获取用户id
        Long userId = UserHolder.getUserId();
        //2.调用api查询
        RecommendUser recommendUser = recommendUserApi.queryWithMaxScore(userId);
        if (recommendUser == null) {
            recommendUser = new RecommendUser();
            recommendUser.setUserId(1L);
            recommendUser.setScore(99d);
        }
        //3.将recommendUser转化为TodayBest对象.
        UserInfo byId = userInfoApi.findById(recommendUser.getUserId());
        TodayBest vo = TodayBest.init(byId, recommendUser);

        //4.返回
        return vo;
    }

    /*查询分页推荐好友列表*/
    /*public PageResult recommendation(RecommendUserDto dto) {
        //1.获取当前用户id
        Long userId = UserHolder.getUserId();
        //2.调用 recommendUserApi分页查询数据列表（PageResult -- RecommendUser）
        PageResult pr = recommendUserApi.queryRecommendUserDto(dto.getPage(),dto.getPagesize(),userId);
        //3.获取分页中的RecommendUser数据列表
        List<RecommendUser> items = (List<RecommendUser>) pr.getItems();
        //4.判断是否为空
        List<TodayBest> list = new ArrayList<>();
        if(items == null){
            return pr;
        }
        //5.循环RecommendUser列表，根据推荐的用户id查询用户详细
        for (RecommendUser item : items) {
            Long recommendUserId = item.getUserId();
            UserInfo userInfo = userInfoApi.findById(recommendUserId);
            if(userInfo!=null){
                if(!StringUtils.isEmpty(dto.getGender())&&!dto.getGender().equals(userInfo.getGender())){
                 continue;}
                 if(dto.getAge()!=null && dto.getAge()<userInfo.getAge()){
                    continue;
                 }
                TodayBest vo = TodayBest.init(userInfo,item);
                list.add(vo);
            }
        }
        pr.setItems(list);
        //6.构造返回值
        return pr;
    }*/
    public PageResult recommendation(RecommendUserDto dto) {
        //1.获取当前用户id
        Long userId = UserHolder.getUserId();
        //2.调用 recommendUserApi分页查询数据列表（PageResult -- RecommendUser）
        PageResult pr = recommendUserApi.queryRecommendUserDto(dto.getPage(), dto.getPagesize(), userId);
        //3.获取分页中的RecommendUser数据列表
        List<RecommendUser> items = (List<RecommendUser>) pr.getItems();
        //4.判断是否为空
        if (items == null) {
            return pr;
        }
        //5.提取所有推荐的用户id列表
        /*List<Long> list = new ArrayList<>();
        for (RecommendUser item : items) {
            Long id = item.getUserId();
            list.add(id);
        }*/
        List<Long> fieldValues = CollUtil.getFieldValues(items, "userId", Long.class);
        UserInfo userInfo = new UserInfo();
        userInfo.setAge(dto.getAge());
        userInfo.setGender(dto.getGender());
        //6.构建查询条件 ，批量查询所有的用户详情
        Map<Long, UserInfo> map = userInfoApi.findByIds(fieldValues, userInfo);
        //7.循环推荐的数据列表，构建vo对象
        List<TodayBest> tlist = new ArrayList<>();
        for (RecommendUser item : items) {
            UserInfo userInfo1 = map.get(item.getUserId());
            if (userInfo1 != null) {
                TodayBest vo = TodayBest.init(userInfo1, item);
                tlist.add(vo);
            }
        }
        pr.setItems(tlist);
        return pr;
    }

    public TodayBest personalInfo(Long userId) {
        //1.根据用户id查询用户详情
        Long Id = UserHolder.getUserId();
        UserInfo userInfo = userInfoApi.findById(userId);
        //2.根据操作人id和查看的用户id，查询两者的推荐数据
        RecommendUser user = recommendUserApi.queryByUserId(userId, Id);
        //构造访客数据，调用API保存
        Visitors visitors = new Visitors();
        visitors.setUserId(userId);
        visitors.setVisitorUserId(Id);
        visitors.setFrom("首页");
        visitors.setDate(System.currentTimeMillis());
        visitors.setVisitDate(new SimpleDateFormat("yyyyMMdd").format(new Date()));
        visitors.setScore(user.getScore());
        visitorsApi.save(visitors);

        //3.构造返回值
        TodayBest init = TodayBest.init(userInfo, user);
        return init;
    }

    public String strangerQuestions(Long userId) {
        Question question = questionApi.findByUserId(userId);
        return question == null ? "你喜欢java吗" : question.getTxt();
    }

    /*回复陌生人问题*/
    public void replystrangerQuestions(Long aLong, String reply) {
        //1.构造消息数据
        Long userId = UserHolder.getUserId();
        UserInfo userInfo = userInfoApi.findById(userId);
        userInfo.getNickname();
        Map map = new HashMap();
        map.put("userId", userId);
        map.put("huanXinId", Constants.HX_USER_PREFIX + userId);
        map.put("nickname", userInfo.getNickname());
        map.put("strangerQuestion", strangerQuestions(aLong));
        map.put("reply", reply);
        String s = JSON.toJSONString(map);
        //2.调用template对象，发送消息
        Boolean aBoolean = template.sendMsg(Constants.HX_USER_PREFIX + aLong, s);
        if (!aBoolean) {
            throw new BusinessException(ErrorResult.error());
        }
    }

    public List<TodayBest> cards() {
        //1、调用推荐API查询数据列表（排除喜欢/不喜欢的用户，数量限制）
        List<RecommendUser> list = recommendUserApi.cards(UserHolder.getUserId(), 10);
        //2、判断数据是否存在，如果不存在，构造默认数据 1,2,3
        if (CollUtil.isEmpty(list)) {
            list = new ArrayList<>();
            String[] userIds = recommendUser.split(",");
            for (String userId : userIds) {
                RecommendUser recommendUser = new RecommendUser();
                recommendUser.setUserId(Convert.toLong(userId));
                recommendUser.setToUserId(UserHolder.getUserId());
                recommendUser.setScore(RandomUtil.randomDouble(60, 90));
                list.add(recommendUser);
            }
        }
        //3.如果存在构造VO
        List<TodayBest> vos = new ArrayList<>();
        List<Long> userId = CollUtil.getFieldValues(list, "userId", Long.class);
        Map<Long, UserInfo> map = userInfoApi.findByIds(userId, null);
        for (RecommendUser user : list) {
            UserInfo userInfo = map.get(user.getUserId());
            if (userInfo != null) {
                TodayBest vo = TodayBest.init(userInfo, user);
                vos.add(vo);
            }
        }
        return vos;
    }

    //探花喜欢
    public void love(Long likeUserId) {
        //1.调用api 保存喜欢数据 mongoDB
        Boolean save = userLikeApi.saveOrupdate(likeUserId, UserHolder.getUserId(), true);
        if (!save) {
            throw new BusinessException(ErrorResult.error());
        }
        //2.操作redis写入喜欢的数据，删除不喜欢的数据
        redisTemplate.opsForSet().remove(Constants.USER_NOT_LIKE_KEY + UserHolder.getUserId(), likeUserId.toString());
        redisTemplate.opsForSet().add(Constants.USER_LIKE_KEY + UserHolder.getUserId(), likeUserId.toString());
        //3.如果双向喜欢
        if (isLike(likeUserId, UserHolder.getUserId())) {
            //4.两者添加为好友
            messagesService.contacts(likeUserId);
        }
    }

    public Boolean isLike(Long userId, Long likeUserId) {
        String key = Constants.USER_LIKE_KEY + UserHolder.getUserId();
        return redisTemplate.opsForSet().isMember(key, likeUserId.toString());
    }

    //不喜欢
    public void unlove(Long likeUserId) {
        Boolean save = userLikeApi.saveOrupdate(likeUserId, UserHolder.getUserId(), false);
        if (!save) {
            throw new BusinessException(ErrorResult.error());
        }
        //2.操作redis写入喜欢的数据，删除喜欢的数据
        redisTemplate.opsForSet().add(Constants.USER_NOT_LIKE_KEY + UserHolder.getUserId(),
                likeUserId.toString());
        redisTemplate.opsForSet().remove(Constants.USER_LIKE_KEY + UserHolder.getUserId(), likeUserId.toString());
        //4.两者删除为好友
    }

    public List<NearUserVo> queryNearUser(String gender, String distance) {
        //1.调用api查询附近的用户（返回的是附近的人的所有的用户id） 设定查询人数 不包含自己
        List<Long> list = userLocationApi.queryNearUser(UserHolder.getUserId(),Double.valueOf(distance));
        //2.判断集合是否为空
        if (CollUtil.isEmpty(list)) {
            return new ArrayList<>();
        }
        //3.如果不为空 查询用户数据（调用userinfoApi）
        UserInfo userInfo = new UserInfo();
        userInfo.setGender(gender);
        Map<Long, UserInfo> map = userInfoApi.findByIds(list, userInfo);
        List<NearUserVo> vos = new ArrayList<>();
        for (Long aLong : list) {
            if(aLong == UserHolder.getUserId()){
                continue;
            }
            UserInfo Info = map.get(aLong);
            if(ObjectUtil.isNotEmpty(Info)){
                NearUserVo vo = NearUserVo.init(userInfo);
                vos.add(vo);
            }

        }
        return vos;
        //4.构造返回值
    }
}
